<html>
<head><meta charset="utf-8"><title>null pointer accesses of size 0 · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html">null pointer accesses of size 0</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="218235582"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218235582" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218235582">(Nov 29 2020 at 23:16)</a>:</h4>
<p>I was reading <a href="https://doc.rust-lang.org/beta/std/ptr/index.html#safety">https://doc.rust-lang.org/beta/std/ptr/index.html#safety</a> and saw</p>
<blockquote>
<ul>
<li>A null pointer is never valid, not even for accesses of size zero.</li>
<li>All pointers (except for the null pointer) are valid for all operations of size zero.</li>
</ul>
</blockquote>
<p>Now, I have no use case here, but why aren't null pointers valid for accesses of size 0 if all other pointers are?</p>



<a name="218235696"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218235696" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218235696">(Nov 29 2020 at 23:19)</a>:</h4>
<p>because optimisations assume that it isn't if its dereferenced.</p>



<a name="218235707"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218235707" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218235707">(Nov 29 2020 at 23:19)</a>:</h4>
<p>… I believe.</p>



<a name="218235711"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218235711" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218235711">(Nov 29 2020 at 23:19)</a>:</h4>
<p>Hmm, for zero size accesses?</p>



<a name="218235754"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218235754" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218235754">(Nov 29 2020 at 23:20)</a>:</h4>
<p>Are those optimizations profitable for zero-sized accesses?</p>



<a name="218235755"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218235755" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218235755">(Nov 29 2020 at 23:20)</a>:</h4>
<p>though in practice we don't generate any code for dereferences, but that's just an implementation detail, really.</p>



<a name="218235793"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218235793" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218235793">(Nov 29 2020 at 23:21)</a>:</h4>
<p>If  it's an implementation detail, wouldn't that mean that "All pointers (except for the null pointer) are valid for all operations of size zero." isn't true? E.g. clearly if i read from <code>1 as *const ()</code> that can't ever generate any code.</p>



<a name="218235836"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218235836" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218235836">(Nov 29 2020 at 23:22)</a>:</h4>
<p>but according to the above <code>*(1 as *const ())</code> is allowed but <code>*(0 as *const ())</code> isn't</p>



<a name="218236779"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218236779" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218236779">(Nov 29 2020 at 23:46)</a>:</h4>
<p>I'd guess it has something to do with layout optimizations (e.g. <code>Option&lt;NonNull&lt;()&gt;&gt;</code>) and/or emitted <code>nonnull</code> attributes for LLVM</p>



<a name="218236821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218236821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218236821">(Nov 29 2020 at 23:47)</a>:</h4>
<p>That doesn't sound right, since it's only about the reads and writes, not about the values. It's totally legal to have null pointers (not null <code>NonNull&lt;T&gt;</code>s, but null <code>*mut T</code>/<code>*const T</code>s)</p>



<a name="218236874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218236874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218236874">(Nov 29 2020 at 23:48)</a>:</h4>
<p>E.g. this function is safe: <a href="https://doc.rust-lang.org/std/ptr/fn.null_mut.html">https://doc.rust-lang.org/std/ptr/fn.null_mut.html</a></p>



<a name="218238946"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218238946" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218238946">(Nov 30 2020 at 00:40)</a>:</h4>
<p>I'd argue that the fact optimizations are only applied to generated code is an implementation-detailed. <br>
For example, an optimization applied to a generic function, before monomorphization.</p>



<a name="218292895"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218292895" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218292895">(Nov 30 2020 at 14:29)</a>:</h4>
<p>note that what the docs say is unfortunately too simplified (and the nightly docs are more precise)</p>



<a name="218292936"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218292936" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218292936">(Nov 30 2020 at 14:29)</a>:</h4>
<blockquote>
<p>Even for operations of size zero, the pointer must not be pointing to deallocated memory, i.e., deallocation makes pointers invalid even for zero-sized operations. However, casting any non-zero integer literal to a pointer is valid for zero-sized accesses, even if some memory happens to exist at that address and gets deallocated. This corresponds to writing your own allocator: allocating zero-sized objects is not very hard. The canonical way to obtain a pointer that is valid for zero-sized accesses is NonNull::dangling.</p>
</blockquote>



<a name="218293071"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218293071" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218293071">(Nov 30 2020 at 14:30)</a>:</h4>
<p>I am not particularly happy about this, but this reflects requirements LLVM imposes on the IR we generate, that we currently have no choice but forward to the user</p>



<a name="218293208"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218293208" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218293208">(Nov 30 2020 at 14:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="123586">nagisa</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200/near/218235755">said</a>:</p>
<blockquote>
<p>though in practice we don't generate any code for dereferences, but that's just an implementation detail, really.</p>
</blockquote>
<p>we don't generate LLVM IR, but we do generate MIR. and MIR optimizations might conclude from a <code>*p</code> that <code>p != NULL</code>, no matter which type <code>p</code> points to. that is the current set of rules anyway; we could relax this but I am unsure of the cost of that.</p>



<a name="218330776"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null%20pointer%20accesses%20of%20size%200/near/218330776" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/null.20pointer.20accesses.20of.20size.200.html#218330776">(Nov 30 2020 at 19:06)</a>:</h4>
<p>We probably won't be able to relax that, unless MIR becomes non-generic.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>